package com.ccb.sc.common.modules.common.service;

import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.script.RedisScript;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 序列号服务
 * </p>
 * @author ken
 * @version 1.0
 * @date 2020-09-15
 */
public interface IRedisService {

    /**
     * 存入redis
     * @param key key
     * @param value value
     */
    void set(String key, Object value);

    /**
     * 存入redis
     * @param key key
     * @param value value
     * @param timeout 过期时间(S)
     */
    void set(String key, Object value, long timeout);

    /**
     * 存入redis
     * @param key key
     * @param value value
     * @param timeout 过期时间
     * @param unit 时间单位
     */
    void set(String key, Object value, long timeout, TimeUnit unit);

    /**
     * 取值
     * @param key key
     * @return value
     */
    Object get(String key);

    /**
     * 存入当天有效的
     * @param key key
     * @param value value
     */
    void setWithDayClean(String key, Object value);

    /**
     * 设置key过期时间
     * @param key key
     * @param timeout 过期时间
     * @param unit 单位
     */
    void expire(String key, long timeout, TimeUnit unit);

    /**
     * 设置key当天有效
     * @param key key
     */
    void expireWithDayClean(String key);

    /**
     * 删除key集合
     * @param keys keys
     */
    void delete(Set<String> keys);

    /**
     * 删除key
     * @param key key
     */
    void delete(String key);

    /***
     * 获取当天天的下个序列号（每天从1开始）
     * @param identityKey 序列号
     * @return 下个自增序列号
     */
    long getNextByDayClean(String identityKey);

    /***
     *  * 获取标准化的序列号  PPYYYYMMDDXXXXX  （PP为前缀，XXXXX增长号）
     * @param key key
     * @param sLength 增长号的长度
     * @return 序列号
     */
    String getNextStandardCodeByDayClean(String key, int sLength);

    /***
     * 获取下个序列号（一直增长的，不清零）
     * @param key key
     * @return 下个序列号
     */
    long getNext(String key);

    /**
     * 执行redis脚本
     * @param script 脚本
     * @param keys keys
     * @param args 参数
     * @param <T> 返回值
     * @return 返回值
     */
    <T> T execute(RedisScript<T> script, List<String> keys, Object... args);

    /**
     * 查找所有key值
     * @param key key
     * @return Set<String>
     */
    Set<String> keys(String key);

    /**
     * redis zset add
     * @param key key
     * @param value key
     * @param score score
     * @return boolean
     */
    boolean zAdd(String key, Object value, double score);

    /**
     * 获取zset value值和score值
     * @param key key
     * @param start 起始位置的index 从0开始
     * @param end 结束位置的index -1表示获取全部
     * @param isReverse 是否倒序
     * @return
     */
    Set<ZSetOperations.TypedTuple<Object>> rangeWithScores(String key, long start, long end, boolean isReverse);

    /**
     * 分布式加锁
     * @param key key
     * @param value value
     * @param expireSecond 过期时间（s）
     * @return boolean 是否加锁成功
     */
    boolean lock(String key, Object value, int expireSecond);

    /**
     * 分布式解锁
     * @param key key
     * @param value value
     * @return boolean 是否解锁成功
     */
    boolean unLock(String key, Object value);
}
